package th.ac.lru.cs.ktd.frame;

import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.text.EditorKit;
import javax.swing.DefaultListModel;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JTabbedPane;
import javax.swing.JLayeredPane;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JEditorPane;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.EventQueue;

import th.ac.lru.cs.ktd.beans.Vocabulary;
import th.ac.lru.cs.ktd.dao.VocabularyDao;
import th.ac.lru.cs.ktd.keyboard.KoreanVirtualKeyboard;

public class DictionaryMainFrame extends JFrame {

	private static final long serialVersionUID = 7014226841036254508L;

	private final String HTML_TYPE = "text/html";
	
	private final String[][] KOREAN_CHAR = {
			{ "ㄱ",    "1",  "766" }, { "ㄲ",  "767",  "849" }, { "ㄴ",  "850", "1093" }, { "ㄷ", "1094", "1459" }, { "ㄸ", "1460", "1527" },
			{ "ㅁ", "1528", "1927" }, { "ㄹ", "1928", "1933" }, { "ㅂ", "1934", "2452" }, { "ㅃ", "2453", "2489" }, { "ㅅ", "2490", "3234" },
			{ "ㅆ", "3235", "3274" }, { "ㅇ", "3275", "4306" }, { "ㅈ", "4307", "5016" }, { "ㅉ", "5017", "5049" }, { "ㅊ", "5050", "5369" },
			{ "ㅋ", "5370", "5401" }, { "ㅌ", "5402", "5538" }, { "ㅍ", "5539", "5720" }, { "ㅎ", "5721", "6140" }
	};

	
	private final char[] THAI_CHAR = {
			'ก', 'ข', 'ค', 'ฆ', 'ง', 'จ', 
			'ฉ', 'ช', 'ซ', 'ฌ', 'ญ', 'ฐ', 
			'ด', 'ต', 'ถ', 'ท', 'ธ', 'น', 
			'บ', 'ป', 'ผ', 'ฝ', 'พ', 'ฟ', 
			'ภ', 'ท', 'ย', 'ร', 'ถ', 'ล', 
			'ว', 'ศ', 'ส', 'ห', 'อ', 'ฮ'
	};
	
	private JPanel 			mContentPane;
	
	private JTextField 		mTextFieldFindVocab;
	private JButton 		mButtonFindVocabulary;
	private JButton 		mButtonFindPronounce;	
	
	private JTabbedPane 	mTabbedPane;
	private JLayeredPane 	mLayeredPaneSearch;
	private JLayeredPane 	mLayeredPaneKorean;
	
	private JEditorPane 	mEditorPaneThaiVocab;
	
	private	JEditorPane 	mEditorPaneVocabSearch;
	private JScrollPane 	mScrollPaneSearchVocab;
	private JEditorPane     mEditorPaneKoreanVocab;
	
	private JMenuBar 		mMenuBar;
	private JMenu 			mMenuFile;
	
	private JMenuItem 		mMenuHowRule1;
	
	private JList 			mListKoreanChar;
	private JList 			mListThaiChar;

	/**
	 * Create the frame.
	 */
	public DictionaryMainFrame() {
		setTitle("Korean Thai Dictionary");
		setResizable(false);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 572, 315);
		
		mMenuBar = new JMenuBar();
		setJMenuBar(mMenuBar);
		
		mMenuFile = new JMenu("แฟ้ม");
		mMenuBar.add(mMenuFile);
		
		JMenuItem mMntmNewMenuFileLookUp = new JMenuItem("ค้นหาคำศัพท์");
		mMntmNewMenuFileLookUp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				mTabbedPane.setSelectedIndex(0);
				mTextFieldFindVocab.requestFocus();
			}
		});
		mMenuFile.add(mMntmNewMenuFileLookUp);
		
		JMenuItem mMntmNewMenuExit = new JMenuItem("ออก");
		mMntmNewMenuExit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				System.exit(0);
			}
		});
		mMenuFile.add(mMntmNewMenuExit);
		
		JMenu mMntmNewMenuEdit = new JMenu("แก้ไข");
		// mMenuBar.add(mMntmNewMenuEdit);
		
		JMenuItem mMntmNewMenuCopyAll = new JMenuItem("เลือกทั้งหมด");
		mMntmNewMenuCopyAll.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		mMntmNewMenuEdit.add(mMntmNewMenuCopyAll);
		
		JMenuItem mMntmNewMenuCopy = new JMenuItem("คัดลอก");
		mMntmNewMenuCopy.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		mMntmNewMenuEdit.add(mMntmNewMenuCopy);
		
		JMenu mMntmNewMenuHowToPronounce = new JMenu("หลักการอ่านเบื้องต้น");
		mMenuBar.add(mMntmNewMenuHowToPronounce);
		
		mMenuHowRule1 = new JMenuItem("หลักการที่ 1");
		mMenuHowRule1.setName("MenuHowRule1");
		mMenuHowRule1.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openInformation(arg0, HtmlContent.getHtmlRule1Content());
			}
		});
		mMntmNewMenuHowToPronounce.add(mMenuHowRule1);
		
		JMenuItem mMntmNewMenuHowRule2 = new JMenuItem("หลักการที่ 2");
		mMntmNewMenuHowRule2.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openInformation(arg0, HtmlContent.getHtmlRule2Content());
			}
		});
		mMntmNewMenuHowToPronounce.add(mMntmNewMenuHowRule2);
		
		JMenuItem mMntmNewMenuHowRule3 = new JMenuItem("หลักการที่ 3");
		mMntmNewMenuHowRule3.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openInformation(arg0, HtmlContent.getHtmlRule3Content());
			}
		});
		mMntmNewMenuHowToPronounce.add(mMntmNewMenuHowRule3);
		
		JMenuItem mMntmNewMenuHowRule4 = new JMenuItem("หลักการที่ 4");
		mMntmNewMenuHowRule4.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openInformation(arg0, HtmlContent.getHtmlRule4Content());
			}
		});
		mMntmNewMenuHowToPronounce.add(mMntmNewMenuHowRule4);
		
		JMenuItem mMntmNewMenuHowRule5 = new JMenuItem("หลักการที่ 5");
		mMntmNewMenuHowRule5.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openInformation(arg0, HtmlContent.getHtmlRule5Content());
			}
		});
		mMntmNewMenuHowToPronounce.add(mMntmNewMenuHowRule5);
		
		JMenu mMntmNewMenuHelp = new JMenu("ช่วยเหลือ");
		mMenuBar.add(mMntmNewMenuHelp);
		
		JMenuItem mMenuHelp = new JMenuItem("ข้อมูลช่วยเหลือ");
		mMenuHelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openInformation(arg0, HtmlContent.getHtmlHelpContent());
			}
		});
		mMntmNewMenuHelp.add(mMenuHelp);
		
		JMenuItem mMntmNewMenuAbout = new JMenuItem("เกี่ยวกับโปรแกรม");
		mMntmNewMenuAbout.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openAbout(arg0);
			}
		});
		mMntmNewMenuHelp.add(mMntmNewMenuAbout);

		mContentPane = new JPanel();
		mContentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(mContentPane);
		mContentPane.setLayout(null);
		
		mTabbedPane = new JTabbedPane(JTabbedPane.TOP);
		mTabbedPane.setBounds(0, 0, 566, 269);
		mContentPane.add(mTabbedPane);
		
		mLayeredPaneSearch = new JLayeredPane();
		mTabbedPane.addTab("ค้นหาคำศัพท์", null, mLayeredPaneSearch, null);
		
		mTextFieldFindVocab = new JTextField();
		mTextFieldFindVocab.setBounds(5, 5, 223, 30);
		mLayeredPaneSearch.add(mTextFieldFindVocab);
		mTextFieldFindVocab.setColumns(50);
		
		mButtonFindVocabulary = new JButton("ค้นหาคำศัพท์");
		mButtonFindVocabulary.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (!mTextFieldFindVocab.getText().equals("")) {
					searchVocabularyByKoreanVocab();	
				}
			}
		});
		mButtonFindVocabulary.setBounds(230, 5, 110, 30);
		mLayeredPaneSearch.add(mButtonFindVocabulary);
		
		mButtonFindPronounce = new JButton("ค้นหาจากคำอ่าน");
		mButtonFindPronounce.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				if (!mTextFieldFindVocab.getText().equals("")) {
					searchVocabularyByKoreanPronounce();
				}
			}
		});
		mButtonFindPronounce.setBounds(339, 5, 110, 30);
		mLayeredPaneSearch.add(mButtonFindPronounce);
		
		JButton mButtonKoreanKeyBoard = new JButton("한글 키보드");
		mButtonKoreanKeyBoard.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				openKoreanKeyboard(arg0);
			}
		});
		mButtonKoreanKeyBoard.setBounds(448, 5, 110, 30);
		mLayeredPaneSearch.add(mButtonKoreanKeyBoard);
		
		mScrollPaneSearchVocab = new JScrollPane();
		mScrollPaneSearchVocab.setEnabled(false);
		mScrollPaneSearchVocab.setBounds(5, 40, 553, 197);
		mLayeredPaneSearch.add(mScrollPaneSearchVocab);
		
		mEditorPaneVocabSearch = new JEditorPane();
		mEditorPaneVocabSearch.setBounds(5, 40, 553, 195);
		mEditorPaneVocabSearch.setEditable(false);
		EditorKit vocabEditKit = mEditorPaneVocabSearch.getEditorKitForContentType(HTML_TYPE);
		mEditorPaneVocabSearch.setEditorKit(vocabEditKit);
		mLayeredPaneSearch.add(mEditorPaneVocabSearch);
		mScrollPaneSearchVocab.setViewportView(mEditorPaneVocabSearch);
		
		
		mLayeredPaneKorean = new JLayeredPane();
		mTabbedPane.addTab("ภาษาไทย", null, mLayeredPaneKorean, null);
		
		DefaultListModel modelThai = new  DefaultListModel();
		for (char tChar : THAI_CHAR) {
			modelThai.addElement(tChar);
		}		
		
		mListThaiChar = new JList(modelThai);
		mListThaiChar.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		mListThaiChar.setBounds(5, 25, 40, 210);
		mLayeredPaneKorean.add(mListThaiChar);
		mListThaiChar.addListSelectionListener(new ListSelectionListener() {
		      public void valueChanged(ListSelectionEvent evt) {
		    	  if (evt.getValueIsAdjusting()) {
		    		  listVocabularyByThaiCharacter(String.valueOf(THAI_CHAR[evt.getLastIndex()]));
		          }
		      }
		});
		
		JScrollPane scrollPaneListThai = new JScrollPane();
		scrollPaneListThai.setBounds(5, 25, 40, 210);
		scrollPaneListThai.setViewportView(mListThaiChar);
		mLayeredPaneKorean.add(scrollPaneListThai);
		
		mEditorPaneThaiVocab = new JEditorPane();
		mEditorPaneThaiVocab.setBounds(50, 25, 505, 210);
		EditorKit editKit = mEditorPaneThaiVocab.getEditorKitForContentType(HTML_TYPE);
		mEditorPaneThaiVocab.setEditorKit(editKit);
		mEditorPaneThaiVocab.setEditable(false);
		mLayeredPaneKorean.add(mEditorPaneThaiVocab);
		
		JScrollPane scrollPaneThaiVoca = new JScrollPane();
		scrollPaneThaiVoca.setEnabled(false);
		scrollPaneThaiVoca.setBounds(50, 25, 505, 210);
		scrollPaneThaiVoca.setViewportView(mEditorPaneThaiVocab);
		mLayeredPaneKorean.add(scrollPaneThaiVoca);
		
		JLabel lblNewLabel = new JLabel("คำศัพท์ ไทย - เกาหลี");
		lblNewLabel.setBounds(5, 5, 148, 14);
		mLayeredPaneKorean.add(lblNewLabel);
		
		JLayeredPane layeredPane_1 = new JLayeredPane();
		mTabbedPane.addTab("한국어", null, layeredPane_1, null);
		
		DefaultListModel modelKorean = new DefaultListModel();
		for (String[] kChar : KOREAN_CHAR) {
			modelKorean.addElement(kChar[0]);
		}
		
		mListKoreanChar = new JList(modelKorean);
		mListKoreanChar.setBounds(5, 25, 40, 210);
		mListKoreanChar.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		
		mListKoreanChar.addListSelectionListener(new ListSelectionListener() {
		      public void valueChanged(ListSelectionEvent evt) {
		    	  if (evt.getValueIsAdjusting()) {
		    		  String[] idx = KOREAN_CHAR[evt.getLastIndex()];
		    		  listVocabularyByKoreanCharacter(Integer.parseInt(idx[1]), Integer.parseInt(idx[2]));
		          }
		      }
		});
		
		layeredPane_1.add(mListKoreanChar);
		
		JScrollPane scrollPaneListKorean = new JScrollPane();
		scrollPaneListKorean.setBounds(5, 25, 40, 210);
		scrollPaneListKorean.setViewportView(mListKoreanChar);
		layeredPane_1.add(scrollPaneListKorean);
		
		mEditorPaneKoreanVocab = new JEditorPane();
		mEditorPaneKoreanVocab.setBounds(50, 25, 505, 210);
		mEditorPaneKoreanVocab.setEditable(false);
		EditorKit vocabEditKit_2 = mEditorPaneKoreanVocab.getEditorKitForContentType(HTML_TYPE);
		mEditorPaneKoreanVocab.setEditorKit(vocabEditKit_2);
		
		layeredPane_1.add(mEditorPaneKoreanVocab);
		
		JScrollPane scrollPaneKoreanVoca = new JScrollPane();
		scrollPaneKoreanVoca.setBounds(50, 25, 505, 210);
		scrollPaneKoreanVoca.setViewportView(mEditorPaneKoreanVocab);
		layeredPane_1.add(scrollPaneKoreanVoca);
		
		JLabel mLabelKoreanThai = new JLabel("คำศัพท์ เกาหลี - ไทย");
		mLabelKoreanThai.setBounds(5, 5, 148, 15);
		layeredPane_1.add(mLabelKoreanThai);
	}
	
	public JTextField getTextFieldFindVocab() {
		return mTextFieldFindVocab;
	}

	public void setTextFieldFindVocab(JTextField mTextFieldFindVocab) {
		this.mTextFieldFindVocab = mTextFieldFindVocab;
	}

	private void searchVocabularyByKoreanVocab() {
		String text = mTextFieldFindVocab.getText().trim();
	    VocabularyDao vocabDao = VocabularyDao.getInstance(); 
	    ArrayList<Vocabulary> vocbList = vocabDao.findVocabularyByVocab(text);
	    mEditorPaneVocabSearch.setText("");
	    if (!vocbList.isEmpty()) {
	    	String display = vocabularyDisplay(vocbList);
	       	mEditorPaneVocabSearch.setText(display);
	       	mEditorPaneVocabSearch.setCaretPosition(0);
	    }
	}
	
	private void searchVocabularyByKoreanPronounce() {
		String text = mTextFieldFindVocab.getText().trim();
	    VocabularyDao vocabDao = VocabularyDao.getInstance(); 
	    ArrayList<Vocabulary> vocbList = vocabDao.findVocabularyByPronounce(text);
	    mEditorPaneVocabSearch.setText("");
	    if (!vocbList.isEmpty()) {
	    	String display = vocabularyDisplay(vocbList);
	       	mEditorPaneVocabSearch.setText(display);
	       	mEditorPaneVocabSearch.setCaretPosition(0);
	    }
	}

	private void listVocabularyByThaiCharacter(String tChar) {
		final String text = tChar;
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
				    VocabularyDao vocabDao = VocabularyDao.getInstance(); 
				    ArrayList<Vocabulary> vocbList = vocabDao.getVocabularyByThaiCharacter(text);
				    mEditorPaneThaiVocab.setText("");
				    if (!vocbList.isEmpty()) {
				    	String display = vocabularyDisplay(vocbList);
				    	mEditorPaneThaiVocab.setText(display);
				    	mEditorPaneThaiVocab.setCaretPosition(0);
				    }					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});			
	}
	
	private void listVocabularyByKoreanCharacter(int fromIndex, int toIndex) {
		final int fromIdx = fromIndex;
		final int toIdx   = toIndex;
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
				    VocabularyDao vocabDao = VocabularyDao.getInstance(); 
				    ArrayList<Vocabulary> vocbList = vocabDao.getVocabularyByKoreanCharacter(fromIdx, toIdx);
				    mEditorPaneKoreanVocab.setText("");
				    if (!vocbList.isEmpty()) {
				    	String display = vocabularyDisplay(vocbList);
				    	mEditorPaneKoreanVocab.setText(display);
				    	mEditorPaneKoreanVocab.setCaretPosition(0);
				    }					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});			
	}	
	
	private String vocabularyDisplay(ArrayList<Vocabulary> vocbList) {
		StringBuilder vocabDisplay = new StringBuilder("");
		for (Vocabulary vocabulary : vocbList) {
			vocabDisplay.append("<font size=\"3\" face=\"tahoma\">");
			vocabDisplay.append("<dl>");
			
			if (!vocabulary.getVocabulary().equals("")) {
		    	vocabDisplay.append("<dt>คำศัพท์</dt>");
		    	vocabDisplay.append("<dd>- <font size=\"5\" face=\"tahoma\">" + vocabulary.getVocabulary() + "</font></dd>");	        		
			}
			
			if (!vocabulary.getVocapronounce().equals("")) {
		    	vocabDisplay.append("<dt>คำอ่าน</dt>");
		    	vocabDisplay.append("<dd>- " + vocabulary.getVocapronounce() + "</dd>");	        		
			}
			
			if (!vocabulary.getVocamean().equals("")) {
		    	vocabDisplay.append("<dt>ความหมาย</dt>");
		    	vocabDisplay.append("<dd>- " + vocabulary.getVocamean() + "</dd>");	        		
			}
			
			if (!vocabulary.getSample().equals("")) {
		    	vocabDisplay.append("<dt>ตัวอย่างประโยค</dt>");
		    	vocabDisplay.append("<dd>- " + vocabulary.getSample() + "</dd>");	        		
			}
				
			if (!vocabulary.getSampronounce().equals("")) {
				vocabDisplay.append("<dt>คำอ่าน</dt>");
		    	vocabDisplay.append("<dd>- " + vocabulary.getSampronounce() + "</dd>");
			}
				
			if (!vocabulary.getSammean().equals("")) {
				vocabDisplay.append("<dt>ความหมาย</dt>");
		    	vocabDisplay.append("<dd>- " + vocabulary.getSammean() + "</dd>");
			}
				
			vocabDisplay.append("</dl>");
			vocabDisplay.append("</font>");
			vocabDisplay.append("<hr/>");
		}
		return vocabDisplay.toString();
	}
	
	private void openKoreanKeyboard(ActionEvent args) {
		final DictionaryMainFrame parent = this;
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					KoreanVirtualKeyboard keyboard = KoreanVirtualKeyboard.getInstance(parent);
					keyboard.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});		
	}
	
	private void openInformation(ActionEvent args, String htmlContent) {
		final String content = htmlContent;
		final DictionaryMainFrame parent = this;
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					InformationLargeFrame infoFrame = InformationLargeFrame.newInstance(parent, content);
					infoFrame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});			
	}
	
	private void openAbout(ActionEvent agrs) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					InformationSmallFrame frame = new InformationSmallFrame(HtmlContent.getHtmlAboutContent());
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});		
	}
}
